home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 119 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.2 KB  |  75 lines

  1. Path: EU.net!sun4nl!xs4all!usenet
  2. From: martijnl@xs4all.nl (Martijn Lievaart)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Virtual Functions: How Implemented?
  5. Date: 2 Jan 1996 15:36:16 GMT
  6. Organization: XS4ALL, networking for the masses
  7. Message-ID: <4cbjdg$dra@news.xs4all.nl>
  8. References: <4c0d23$33n@vixen.cso.uiuc.edu>
  9. NNTP-Posting-Host: mas01-15.dial.xs4all.nl
  10. X-Newsreader: WinVN 0.99.6
  11.  
  12. In article <4c0d23$33n@vixen.cso.uiuc.edu>, sjmccaug@prairienet.orgĂ® says...
  13. >
  14. >
  15. > // suppose base-class 'bc' was defined earlier ...
  16. >
  17. > dc1 dco1; // dc1 is the first class derived from 'bc'
  18. > dc2 dco2; // dc2 is the second derived class
  19. > int x,y;
  20. >
  21. > . . . . .
  22. >
  23. > bc *bc_ptr  =  x < y ? &dc01 : &dc02;  // x,y defined at runtime
  24. >
  25. > base-class 'bc' contains a virtual function: value(), which gets re-defined
  26. > in bothe 'dc1' and 'dc2'. If the type argument to a cast operator could be
  27. > determined at runtime, one could say:
  28. >
  29. >            ( (bc_ptr->_type_) * )bc_ptr->value();
  30. >
  31. > where '_type_' is an internal field of each instantiated object that carries
  32. > its class for runtime determination and is itself initialized upon 
  33. instantia-
  34. > tion.
  35. > Since the type argument to a cast is NOT runtime-computable, how is the 
  36. virtual
  37. > function scheme implemented?
  38.  
  39. It's done using so-called vtables. It works like this. A (hidden) data member 
  40. is added to bc and all it's derived classes, the vtable pointer. This points 
  41. to a table that contains the adresses of the virtual functions. The statement 
  42. bc_ptr->value() would get the adress of the function from the table. If bc_ptr 
  43. points to a dc1 then the vtable from that object is used wich ofcourse points 
  44. to the vtable of dc1 and dc1::value() will be called.
  45.  
  46. Confused? picture this.
  47. In c you could do the same by adding a function ptr to your struct. Whenever 
  48. you construct a new object, you would fill in this ptr with the appropriate 
  49. adress (i.e. bc_value, dc1_value).
  50. When you want to compute value you would do something like:
  51.     (*bc_ptr->pvalue)()
  52. and the right function would be called. It is what you try to create above.
  53. There is only one thing wrong with this technique, when you have more than one 
  54. 'virtual' function ptr, these are duplicated in every object. Therefore c++ 
  55. constructs 1 table per class (the vtable for that class) and adds a ptr to 
  56. that table, thereby taking only space for one pointer instead of several.
  57.  
  58. Some observations can be made about this, sometimes you have to be aware of 
  59. these, though they are mostly moot.
  60. - The size of any class with virtual functions is bigger than of the same 
  61. class without, because the vtable ptr is added to the class.
  62. - You cannot rely on the ordering of the members as the vtable ptr is inserted 
  63. (usualy at the start of the object). (you can not anyhow, except when you make 
  64. all members public i.e. a c-struct)
  65. - Virtual functions take two ptr dereferences and therefore are slower than 
  66. nonvirtual functions. But it is an efficient way to do what you want if you 
  67. need the functionality. If you really, really, really, really, really, really, 
  68. really need the utmost speed (hey, liven up, this is the age of the Pentium!), 
  69. try to do it the 'c-ish way' and see if that helps. Most of the time redisign 
  70. of algorithms works better though.
  71.  
  72. Wow, long story, hope this helps.
  73.  
  74.  
  75.